<template>
  <div>
<!--    单个坐标点-->
    <div id="maps"></div>
    <div ref="popup" class="popup" v-show="shopPopup">
      <div class="info">
        <ul>
          <li>信息1：xxx</li>
        </ul>
      </div>
    </div>
  </div>
</template>

<script>
import {Map, View, Feature, Overlay} from "ol"  //Feature类 ---->要素，即地图上的几何对象，包括点Point、线LineString、多边形Polygon、圆Circle,用ol.interaction.Drew绘制
import TileLayer from "ol/layer/Tile"   //瓦片
import XYZ from "ol/source/XYZ"; //xyz的方式加载地图    x-->瓦片行号；y-->瓦片列号；z-->瓦片级数
import * as olProj from "ol/proj" //地图中的坐标系相互转换的包
import {Style, Fill, Stroke, Circle as sCircle} from "ol/style";  //ol/style 地图样式 Fill-->要填充要素的样式  Stroke-->要素边界样式  Circle-->针对矢量要素设置圆形样式
import {Point} from "ol/geom";
import {Vector as VectorLayer} from "ol/layer"  //矢量图层
import {Vector as VectorSource} from "ol/source"  //矢量数据

export default {
  name: "Maps",
  data() {
    return {
      openMap: null,
      shopPopup: false,
      popup: null,
    }
  },
  mounted() {
    this.initMap()
  },
  methods: {
    initMap() {
      this.openMap = new Map({
        target: "maps",
        layers: [
          new TileLayer({
            source: new XYZ({
              //openMap的瓦片地址
              url: "https://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x={x}&y={y}&z={z}"
            })
          })
        ],
        view: new View({
          center: olProj.fromLonLat([108.945951, 34.465262]),  //fromLonLat(coordinate,destination) 把当前坐标coordinate转到目标投影坐标系destination
          zoom: 12
        }),
        controls: []
      })
      this.setMarker()
      this.singleClick()
      this.pointerMove()
      this.addOverlay()
    },
    setMarker() {
      let _style = new Style({
        image: new sCircle({
          radius: 15,
          stroke: new Stroke({
            color: "black",  //线条颜色
          }),
          fill: new Fill({
            color: "red",
          }),
        }),
      });
      let _feature = new Feature({
        geometry: new Point(olProj.fromLonLat([108.945951, 34.465262])),  //geometry 几何属性，一个Feature只有一个默认分几何属性
      });
      _feature.setStyle(_style);  //设置点要素的样式
      //实例化一个矢量图层
      let _marker = new VectorLayer({  //VectorLayer 添加矢量图层
        source: new VectorSource({   //source 绘制要素的目标图层源
          features: [_feature],  //features 绘制要素的目标集合
        }),
      });
      //添加指定图层
      //Layers用来盛放地图上的各种元素，从下到上显示
      this.openMap.addLayer(_marker);
    },
    //点击事件
    singleClick() {
      this.openMap.on("singleclick", (e) => {
        this.shopPopup = false
        //判断是否点击在点上,点击在点上就返回Feature信息
        this.openMap.forEachFeatureAtPixel(  //forEachFeatureAtPixel 配合e.pixel读取到与视图端口相交的像素，有相交的就进行后续操作
            e.pixel,
            (feature) => {
              this.shopPopup = true;
              //设置弹窗位置
              // getCoordinates() 返回线段坐标  getGeometry() 获取默认几何属性
              let coordinates = feature.getGeometry().getCoordinates()
              this.popup.setPosition(coordinates)  //setPosition设置位置，若位置为undefined，则覆盖被隐藏
            }
        );
      })
    },
    //  鼠标移动到点位的光标样式
    pointerMove() {
      this.openMap.on("pointermove", (e) => {  //pointermove 地图平移时触发/鼠标移动时触发
        if (this.openMap.hasFeatureAtPixel(e.pixel)) {  //通过e.pixel判断在视图地图上是否有相交的像素，有的话改变鼠标样式
          this.openMap.getViewport().style.cursor = "pointer";  //getViewport() 获取作为map视图的元素
        } else {
          this.openMap.getViewport().style.cursor = "inherit"
        }
      })
    },
    addOverlay() {
      //  创建Overlay ----->  要显示在地图上方，且附加到单个地图位置的元素（不在地图上固定位置，要绑定在地理坐标上）
      let elPopup = this.$refs.popup
      this.popup = new Overlay({
        element: elPopup,  // element Dom元素
        positioning: "bottom-right", // 设置overlay相对于坐标的位置
        stopEvent: false, // 是否应该停止到map视图的事件传播，若为true，在map层用on监听的事件都会无用
        //true--->Overlay层被放在装载控件的div容器里（该div容器css类名为ol-overlaycontainer-stopevent）
        //false--->Overlay层被放在css类名为ol-overlaycontainer的div容器下
        offset: [0, -20] //偏移量（水平偏移--左负右正，垂直偏移--上负下正）
      })
      this.openMap.addOverlay(this.popup)  // 将Overlay添加到地图中
    },
  }
}
</script>

<style scoped>
#maps {
  width: 100vw;
  height: 100vh;
}

.popup {
  width: 200px;
  background-color: white;
  padding: 18px;
  border-radius: 10px;
  box-shadow: 0 0 15px rgb(177, 177, 177);
}

.info {
  font-size: 14px;
  text-align: left;
}

ul {
  padding-left: 0;
}
</style>
